//
//  MCNNavigationBar.swift
//  MCNNavigationBar
//
//  Created by yhbj on 2021/9/16.
//

import UIKit

class MCNNavigationBar: UIView {
    /**
     设置左右Button的大小(宽高相等)
     */
    var mcn_itemSize: CGFloat = 44 {
        didSet {
            shouldRefLayout = true
            relayoutSubviews()
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64(CGFloat.leastNonzeroMagnitude * CGFloat(NSEC_PER_SEC)))) {
                self.relayoutSubviews()
            }
        }
    }
    /**
     设置Item之间的间距
     */
    var mcn_itemMargin: CGFloat = 10 {
        didSet {
            shouldRefLayout = true
            relayoutSubviews()
        }
    }
    /**
     最左侧Button
     */
    var mcn_leftBtn: MCNNavItemButton?
    /**
     左侧第二个Button
     */
    var mcn_subLeftBtn: MCNNavItemButton?
    /**
     最右侧Button
     */
    var mcn_rightBtn: MCNNavItemButton?
    /**
     右侧第二个Button
     */
    var mcn_subRightBtn: MCNNavItemButton?
    /**
     titleView，显示在正中间的标题View
     */
    private(set) var mcn_titleView: MCNNavTitleView?
    /**
     titleLabel，显示在正中间的标题Label
     */
    var mcn_titleLabel: MCNNavTitleLabel?
    /**
     导航栏背景ImageView
     */
    var mcn_backImageView: MCNNavBackImageView?
    /**
     导航栏背景渐变的CAGradientLayer
     */
    var mcn_gradientLayer: CAGradientLayer? {
        didSet {
            if oldValue != nil && mcn_gradientLayer == nil {
                oldValue?.removeFromSuperlayer()
            }
            if mcn_gradientLayer != nil {
                if oldValue != nil {
                    oldValue?.removeFromSuperlayer()
                }
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64(CGFloat.leastNonzeroMagnitude * CGFloat(NSEC_PER_SEC)))) {
                    self.layer.insertSublayer(self.mcn_gradientLayer!, at: 0)
                }
            }
        }
    }
    /**
     导航栏背景图片
     */
    var mcn_backImage: UIImage? {
        didSet {
            mcn_backImageView?.image = mcn_backImage
        }
    }
    /**
     是否开启系统导航栏与自定义导航栏平滑过渡(务必仅当存在系统导航栏与自定义导航栏过渡时启用，非必要请勿启用，否则可能造成自定义导航栏跳动，若当前控制器显示了系统导航栏，请于当前控制器pop的上一个控制器中使用self.zx_navEnableSmoothFromSystemNavBar = YES)
     */
    private(set) var mcn_navEnableSmoothFromSystemNavBar: Bool = true
    /**
     自定义的titleView，是TitleView的SubView
     */
    var mcn_customTitleView: UIView?
    /**
     自定义的导航栏View，是ZXNavigationBar的SubView
     */
    var mcn_customNavBar: UIView?
    /**
     分割线
     */
    var mcn_lineView: UIView?
    /**
     分割线的高度，默认为1
     */
    var mcn_lineViewHeight: CGFloat = 1 {
        didSet {
            shouldRefLayout = true
            relayoutSubviews()
        }
    }
    /**
     最左侧Button点击回调
     */
    var mcn_leftBtnClickedBlock: ((_ btn: MCNNavItemButton) -> ())?
    /**
     左侧第二个Button点击回调
     */
    var mcn_subLeftBtnClickedBlock: ((_ btn: MCNNavItemButton) -> ())?
    /**
     最右侧Button点击回调
     */
    var mcn_rightBtnClickedBlock: ((_ btn: MCNNavItemButton) -> ())?
    /**
     右侧第二个Button点击回调
     */
    var mcn_subRightBtnClickedBlock: ((_ btn: MCNNavItemButton) -> ())?

    /**
     导航栏背景色Components
     */
    private(set) var mcn_backgroundColorComponents: [CGFloat] = []
    
    private var shouldRefLayout: Bool = false
    private var shouldRefLayoutSubviews: Bool = false
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        initNavBar()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        if !shouldRefLayoutSubviews {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64.init(CGFloat.leastNonzeroMagnitude * CGFloat(NSEC_PER_SEC)))) {
                self.shouldRefLayoutSubviews = true
                self.shouldRefLayout = true
                self.relayoutSubviews()
            }
        } else {
            relayoutSubviews()
        }
    }
    
    private func initNavBar() {
        backgroundColor = MCNNavDefaultBackColor
        mcn_itemSize = MCNNavDefaultItemSize
        mcn_itemMargin = MCNNavDefaultItemMargin
        mcn_lineViewHeight = 0.5
        
        mcn_backImageView = MCNNavBackImageView()
        mcn_backImageView!.clipsToBounds = true
        mcn_backImageView!.contentMode = .scaleAspectFill
        addSubview(mcn_backImageView!)
        
        mcn_leftBtn = MCNNavItemButton()
        mcn_leftBtn!.addTarget(self, action: #selector(leftBtnAction(sender:)), for: .touchUpInside)
        configBtn(sender: mcn_leftBtn!)
        
        mcn_rightBtn = MCNNavItemButton()
        mcn_rightBtn!.addTarget(self, action: #selector(rightBtnAction(sender:)), for: .touchUpInside)
        configBtn(sender: mcn_rightBtn!)
        
        mcn_subRightBtn = MCNNavItemButton()
        mcn_subRightBtn!.addTarget(self, action: #selector(rightBtnAction(sender:)), for: .touchUpInside)
        configBtn(sender: mcn_subRightBtn!)
        
        mcn_subLeftBtn = MCNNavItemButton()
        mcn_subLeftBtn!.addTarget(self, action: #selector(rightBtnAction(sender:)), for: .touchUpInside)
        configBtn(sender: mcn_subLeftBtn!)
        
        mcn_titleView = MCNNavTitleView()
        mcn_titleLabel = MCNNavTitleLabel()
        mcn_titleLabel!.textAlignment = .center
        mcn_titleLabel!.font = UIFont.boldSystemFont(ofSize: MCNNavDefaultTitleSize)
        mcn_titleLabel!.numberOfLines = 1
        mcn_titleLabel!.textColor = MCNNavDefaultTitleColor
        
        mcn_lineView = UIView()
        mcn_lineView!.backgroundColor = MCNNavDefaultLineColor
        addSubview(mcn_leftBtn!)
        addSubview(mcn_rightBtn!)
        addSubview(mcn_subRightBtn!)
        addSubview(mcn_subLeftBtn!)
        addSubview(mcn_titleLabel!)
        addSubview(mcn_titleView!)
        addSubview(mcn_lineView!)
        
        mcn_rightBtn?.mcn_barItemBtnFrameUpdateBlock = { [weak self] baritemBtn in
            self?.shouldRefLayout = true
            self?.relayoutSubviews()
        }
        mcn_subRightBtn?.mcn_barItemBtnFrameUpdateBlock = { [weak self] baritemBtn in
            self?.shouldRefLayout = true
            self?.relayoutSubviews()
        }
        mcn_leftBtn?.mcn_barItemBtnFrameUpdateBlock = { [weak self] baritemBtn in
            self?.shouldRefLayout = true
            self?.relayoutSubviews()
        }
        mcn_subLeftBtn?.mcn_barItemBtnFrameUpdateBlock = { [weak self] baritemBtn in
            self?.shouldRefLayout = true
            self?.relayoutSubviews()
        }
    }
    
    private func configBtn(sender: MCNNavItemButton) {
        sender.titleLabel?.font = UIFont.systemFont(ofSize: MCNNavDefaultItemFontSize)
        sender.titleLabel?.textAlignment = .center
        sender.setTitleColor(MCNNavDefaultItemTextColor, for: .normal)
        sender.titleLabel?.adjustsFontSizeToFitWidth = true
    }
    
    //MARK: - 获取itembtn初始高度
    private func getInitItemBtnHeight(barItemBtn: MCNNavItemButton) -> CGFloat {
        if barItemBtn.mcn_fixHeight >= 0 {
            return barItemBtn.mcn_fixHeight
        }
        return mcn_itemSize
    }
    
    //MARK: - 获取itembtn初始宽度
    private func getInitItemBtnWidth(barItemBtn: MCNNavItemButton) -> CGFloat {
        if barItemBtn.mcn_fixWidth >= 0 {
            return barItemBtn.mcn_fixWidth
        }
        return mcn_itemSize
    }
    
    //MARK: - 获取itembtn最终高度
    private func getItemBtnHeight(barItemBtn: MCNNavItemButton) -> CGFloat {
        if barItemBtn.mcn_fixHeight >= 0 {
            return barItemBtn.mcn_fixHeight
        }
        if (barItemBtn.currentTitle != nil && barItemBtn.currentTitle!.count > 0) || (barItemBtn.currentAttributedTitle != nil && barItemBtn.currentAttributedTitle!.length > 0) {
            return mcn_itemSize + barItemBtn.mcn_textAttachHeight
        }
        return mcn_itemSize
    }
    
    //MARK: - 获取itembtn最终宽度
    private func getItemBtnWidth(barItemBtn: MCNNavItemButton) -> CGFloat {
        if barItemBtn.mcn_fixWidth >= 0 {
            return barItemBtn.mcn_fixWidth
        }
        if barItemBtn.currentAttributedTitle != nil && barItemBtn.currentAttributedTitle!.length > 0 {
            var btnw = barItemBtn.currentAttributedTitle!.mcn_getAttrRectWidth(limitH: barItemBtn.mcn_height, fontSize: barItemBtn.titleLabel!.font.pointSize)
            if barItemBtn.imageView?.image != nil {
                btnw = btnw + barItemBtn.imageView!.mcn_width
            }
            return btnw + barItemBtn.mcn_textAttachWidth + 5
        } else if barItemBtn.currentTitle != nil {
            var btnw = barItemBtn.currentAttributedTitle!.mcn_getAttrRectWidth(limitH: barItemBtn.mcn_height, fontSize: barItemBtn.titleLabel!.font.pointSize)
            if barItemBtn.currentTitle!.count == 0 {
                btnw = 0
            }
            if barItemBtn.imageView?.image != nil {
                btnw = btnw + barItemBtn.imageView!.mcn_width
            }
            return btnw + barItemBtn.mcn_textAttachWidth + 5
        }
        return mcn_itemSize
    }
    
    //MARK: - 拦截处理itembtn的frame
    private func handleItemBtnFrame(barItemBtn: MCNNavItemButton) {
        if barItemBtn.mcn_handleFrameBlock != nil {
            barItemBtn.frame = barItemBtn.mcn_handleFrameBlock!(barItemBtn.frame)
        }
        if barItemBtn.mcn_setCornerRadiusRounded {
            barItemBtn.clipsToBounds = true
            barItemBtn.layer.cornerRadius = barItemBtn.frame.height / 2
        } else if barItemBtn.layer.cornerRadius == barItemBtn.frame.height / 2 {
            barItemBtn.layer.cornerRadius = 0
        }
    }
    
    //MARK: - 刷新导航栏titleview布局
    private func refNavBar() {
        mcn_titleLabel!.mcn_width = mcn_rightBtn!.mcn_left - mcn_itemMargin * 3 - mcn_itemSize
        mcn_titleView!.mcn_width = mcn_titleLabel!.mcn_width
    }
    
    //MARK: - 点击了左侧button
    @objc func leftBtnAction(sender: MCNNavItemButton) {
        if mcn_leftBtnClickedBlock != nil {
            mcn_leftBtnClickedBlock!(sender)
        }
    }
    
    //MARK: - 点击了左侧第二个button
    @objc func subLeftBtnAction(sender: MCNNavItemButton) {
        if mcn_subLeftBtnClickedBlock != nil {
            mcn_subLeftBtnClickedBlock!(sender)
        }
    }
    
    //MARK: - 点击了右侧button
    @objc func rightBtnAction(sender: MCNNavItemButton) {
        if mcn_rightBtnClickedBlock != nil {
            mcn_rightBtnClickedBlock!(sender)
        }
    }
    
    //MARK: - 点击了右侧第二个button
    @objc func subRightBtnAction(sender: MCNNavItemButton) {
        if mcn_subRightBtnClickedBlock != nil {
            mcn_subRightBtnClickedBlock!(sender)
        }
    }
    
    //MARK: - 刷新子控件布局
    private func relayoutSubviews() {
        if !shouldRefLayoutSubviews {
            if mcn_leftBtn!.frame == .zero {
                mcn_leftBtn!.mcn_width = getInitItemBtnWidth(barItemBtn: mcn_leftBtn!)
                mcn_leftBtn!.mcn_height = getInitItemBtnHeight(barItemBtn: mcn_leftBtn!)
            }
            if mcn_rightBtn!.frame == .zero {
                mcn_rightBtn!.mcn_width = getInitItemBtnWidth(barItemBtn: mcn_rightBtn!)
                mcn_rightBtn!.mcn_height = getInitItemBtnHeight(barItemBtn: mcn_rightBtn!)
            }
            return
        }
        if mcn_leftBtn != nil && mcn_rightBtn != nil && mcn_titleLabel != nil {
            let centerOffset = MCNAppStutsBarHeight
            var leftBtnSize = CGSize.zero
            let leftBtnFinalHeight = getInitItemBtnHeight(barItemBtn: mcn_leftBtn!)
            let leftBtnFinalWidth = getInitItemBtnWidth(barItemBtn: mcn_leftBtn!)
            if mcn_leftBtn!.currentImage != nil || mcn_leftBtn!.currentTitle != nil || mcn_leftBtn!.currentAttributedTitle != nil || mcn_leftBtn!.mcn_customView != nil {
                leftBtnSize = CGSize(width: leftBtnFinalWidth, height: leftBtnFinalHeight)
            }
            var leftBtnLeftMargin = mcn_itemMargin
            if mcn_leftBtn!.mcn_fixMarginLeft >= 0 {
                leftBtnLeftMargin = mcn_leftBtn!.mcn_fixMarginLeft
            }
            mcn_leftBtn!.frame = CGRect(x: leftBtnLeftMargin + MCNHorizontaledSafeArea, y: (mcn_height - leftBtnFinalHeight + centerOffset) / 2, width: leftBtnSize.width, height: leftBtnSize.height)
            handleItemBtnFrame(barItemBtn: mcn_leftBtn!)
            var rightBtnSize = CGSize.zero
            let rightBtnFinalHeight = getInitItemBtnHeight(barItemBtn: mcn_rightBtn!)
            let rightBtnFinalWidth = getInitItemBtnWidth(barItemBtn: mcn_rightBtn!)
            if mcn_rightBtn!.currentImage != nil || mcn_rightBtn!.currentTitle != nil || mcn_rightBtn!.currentAttributedTitle != nil || mcn_rightBtn!.mcn_customView != nil {
                rightBtnSize = CGSize(width: rightBtnFinalWidth, height: rightBtnFinalHeight)
            }
            var rightBtnRightMargin = mcn_itemMargin
            if mcn_rightBtn!.mcn_fixMarginRight >= 0 {
                rightBtnRightMargin = mcn_rightBtn!.mcn_fixMarginRight
            }
            mcn_rightBtn!.frame = CGRect(x: mcn_width - rightBtnRightMargin - rightBtnSize.width - MCNHorizontaledSafeArea, y: (mcn_height - rightBtnFinalHeight + centerOffset) / 2, width: rightBtnSize.width, height: rightBtnSize.height)
            handleItemBtnFrame(barItemBtn: mcn_rightBtn!)
            let subRightBtnFinalHeight = getInitItemBtnHeight(barItemBtn: mcn_subRightBtn!)
            let subRightBtnFinalWidth = getInitItemBtnWidth(barItemBtn: mcn_subRightBtn!)
            var subRightBtnRightMargin = mcn_itemMargin
            if mcn_rightBtn!.mcn_fixMarginLeft >= 0 {
                subRightBtnRightMargin = mcn_rightBtn!.mcn_fixMarginLeft
            }
            if mcn_subRightBtn!.mcn_fixMarginRight >= 0 {
                subRightBtnRightMargin = mcn_subRightBtn!.mcn_fixMarginRight
            }
            let subRightBtnRightFinalMargin = mcn_rightBtn!.mcn_width > 0 ? subRightBtnRightMargin : 0
            if mcn_subRightBtn!.currentImage == nil && mcn_subRightBtn!.currentTitle == nil && mcn_subRightBtn!.currentAttributedTitle == nil && mcn_subRightBtn!.mcn_customView == nil {
                mcn_subRightBtn?.frame = CGRect(x: mcn_rightBtn!.mcn_left - subRightBtnRightFinalMargin, y: mcn_rightBtn!.mcn_y, width: 0, height: 0)
            } else {
                mcn_subRightBtn?.frame = CGRect(x: mcn_rightBtn!.mcn_left - subRightBtnRightFinalMargin - subRightBtnFinalWidth, y: (mcn_height - subRightBtnFinalHeight + centerOffset) / 2, width: subRightBtnFinalWidth, height: subRightBtnFinalHeight)
            }
            handleItemBtnFrame(barItemBtn: mcn_subRightBtn!)
            let subLeftBtnFinalHeight = getInitItemBtnHeight(barItemBtn: mcn_subLeftBtn!)
            let subLeftBtnFinalWidth = getInitItemBtnWidth(barItemBtn: mcn_subLeftBtn!)
            var subLeftBtnLeftMargin = mcn_itemMargin
            if mcn_leftBtn!.mcn_fixMarginRight >= 0 {
                subLeftBtnLeftMargin = mcn_leftBtn!.mcn_fixMarginRight
            }
            if mcn_subLeftBtn!.mcn_fixMarginLeft >= 0 {
                subLeftBtnLeftMargin = mcn_subLeftBtn!.mcn_fixMarginLeft
            }
            let subLeftBtnLeftFinalMargin = mcn_leftBtn!.mcn_width > 0 ? subLeftBtnLeftMargin : 0
            if mcn_subLeftBtn!.currentImage == nil && mcn_subLeftBtn!.currentTitle == nil && mcn_subLeftBtn!.currentAttributedTitle == nil && mcn_subLeftBtn!.mcn_customView == nil {
                mcn_subLeftBtn?.frame = CGRect(x: mcn_leftBtn!.mcn_right - subLeftBtnLeftFinalMargin, y: mcn_leftBtn!.mcn_y, width: 0, height: 0)
            } else {
                mcn_subLeftBtn?.frame = CGRect(x: mcn_leftBtn!.mcn_right - subLeftBtnLeftFinalMargin - subLeftBtnFinalWidth, y: (mcn_height - subLeftBtnFinalHeight + centerOffset) / 2, width: subLeftBtnFinalWidth, height: subLeftBtnFinalHeight)
            }
            handleItemBtnFrame(barItemBtn: mcn_subLeftBtn!)
            var leftBtnFakeWidth = mcn_subLeftBtn!.mcn_right
            var titleLabelLeftMargin = mcn_itemMargin
            if mcn_subLeftBtn!.mcn_fixMarginRight >= 0 {
                titleLabelLeftMargin = mcn_subLeftBtn!.mcn_fixMarginRight
            }
            var titleLabelRightMargin = mcn_itemMargin
            if mcn_subRightBtn!.mcn_fixMarginLeft >= 0 {
                titleLabelRightMargin = mcn_subRightBtn!.mcn_fixMarginLeft
            }
            if mcn_subLeftBtn!.mcn_width > 0 {
                leftBtnFakeWidth += titleLabelLeftMargin
            }
            var rightBtnFakeWidth = mcn_width - mcn_subRightBtn!.mcn_x
            if mcn_subRightBtn!.mcn_width > 0 {
                rightBtnFakeWidth += titleLabelRightMargin
            }
            let maxItemWidth = CGFloat.maximum(leftBtnFakeWidth, rightBtnFakeWidth)
            mcn_titleLabel?.frame = CGRect(x: maxItemWidth, y: centerOffset, width: mcn_width - maxItemWidth * 2, height: mcn_height - centerOffset)
            mcn_titleView?.frame = mcn_titleLabel!.frame
            mcn_lineView?.frame = CGRect(x: 0, y: mcn_height - mcn_lineViewHeight, width: mcn_width, height: mcn_lineViewHeight)
            mcn_backImageView?.frame = frame
            shouldRefLayout = false
        }
        if mcn_gradientLayer != nil {
            mcn_gradientLayer?.frame = bounds
        }
        if mcn_customNavBar != nil {
            mcn_customNavBar?.frame = bounds
        }
        if mcn_customTitleView != nil  {
            mcn_customTitleView?.frame = mcn_titleView!.frame
        }
    }
    
    //MARK: - setter
    override var backgroundColor: UIColor? {
        didSet {
            guard let bgColor = backgroundColor else { return }
            if mcn_navEnableSmoothFromSystemNavBar {
                UIApplication.shared.keyWindow?.backgroundColor = bgColor
            }
            var components: [CGFloat] = []
            let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
            var resultingPixel: UnsafeMutablePointer? = UnsafeMutablePointer<Any>.init(bitPattern: 4)
            let context = CGContext.init(data: &resultingPixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)
            context?.setFillColor(bgColor.cgColor)
            context?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            for index in 0..<components.count {
                let component = components[index]
                components[index] = component / 255.0
            }
            mcn_backgroundColorComponents = [components[0], components[1], components[2]]
        }
    }
    
    func privateSetBackgroundColor(backgroundColor: UIColor) {
        self.backgroundColor = backgroundColor
    }
    
    /**
     设置大小标题效果

     @param title 大标题
     @param subTitle 小标题
     @param subTitleFont 小标题字体
     @param subTitleColor 小标题颜色
     */
    func mcn_setMulti(title: String, subTitle: String, subTitleFont: UIFont, subTitleTextColor: UIColor) {
        let appendedStr = title + "\n" + subTitle
        let titleAttributeString = NSMutableAttributedString.init(string: appendedStr)
        titleAttributeString.addAttributes([.font : subTitleFont], range: NSRange(location: title.count, length: appendedStr.count - title.count))
        titleAttributeString.addAttributes([.foregroundColor : subTitleTextColor as Any], range: NSRange(location: title.count, length: appendedStr.count - title.count))
        mcn_titleLabel!.numberOfLines = 2
        mcn_titleLabel?.attributedText = titleAttributeString
    }
    
    /**
     设置大小标题效果

     @param title 大标题
     @param subTitle 小标题
     @param subTitleFont 小标题字体
     @param subTitleColor 小标题颜色
     */
    func mcn_setMulti(title: String, subTitle: String) {
        mcn_setMulti(title: title, subTitle: subTitle, subTitleFont: UIFont.systemFont(ofSize: MCNNavDefaultSubTItleSize), subTitleTextColor: mcn_titleLabel!.textColor)
    }
}
